//---------------------------------------------------------------------
// File: SendPortConductorStep.cs
// 
// Summary: 
//---------------------------------------------------------------------
using System;
using System.Xml;
using BizUnit.BizUnitOM;
using Microsoft.BizTalk.ExplorerOM;

namespace BizUnit.Extensions.BizTalk
{
    using Helpers;

    /// <summary>
    /// The SendPortConductorStep starts/stops a send port.
    /// </summary>

    /// <remarks>
    /// The following shows an example of the Xml representation of this test step.
    /// 
    /// <code escaped="true">
    /// <TestStep assemblyPath="BizUnit.Extensions.BizTalk." typeName="BizUnit.Extensions.BizTalk.SendPortConductorStep">
    ///		<DelayForCompletion>5</DelayForCompletion> <!-- Optional, seconds to delay for this step to complete -->
    ///		<SendPortName></SendPortName>
    ///		<Action>Enable</Action>
    /// </TestStep>
    /// </code>
    ///	
    ///	<list type="table">
    ///		<listheader>
    ///			<term>Tag</term>
    ///			<description>Description</description>
    ///		</listheader>
    ///		<item>
    ///			<term>DelayForCompletion</term>
    ///			<description>The number of seconds to deplay for this step to complete</description>
    ///		</item>
    ///		<item>
    ///			<term>SendPortName</term>
    ///			<description>The name of the receive port to containing the receive location to enable/dissable</description>
    ///		</item>
    ///		<item>
    ///			<term>Action</term>
    ///			<description>Start|Stop</description>
    ///		</item>
    ///	</list>
    ///	</remarks>

    public class SendPortConductorStep : ITestStep, ITestStepOM
    {
        public enum SendPortAction
        {
            Start,
            Stop,
        }

        private BtsCatalogExplorer root;
        private IBizTalkApplication appInstance;
        private SendPort sendPortInstance;

        private string applicationName;
        private string connectionString;
        private string sendPortName;
        private SendPortAction action;
        private int delayForCompletion;

        public SendPortAction Action
        {
            get
            {
                return action;
            }
            set
            {
                action = value;
            }
        }
        public string ApplicationName
        {
            get
            {
                return applicationName;
            }
            set
            {
                applicationName = value;
            }
        }
        public string ConnectionString
        {
            get
            {
                return connectionString;
            }
            set
            {
                connectionString = value;
            }
        }
        public int DelayForCompletion
        {
            get
            {
                return delayForCompletion;
            }
            set
            {
                delayForCompletion = value;
            }
        }
        public string SendPortName
        {
            get
            {
                return sendPortName;
            }
            set
            {
                sendPortName = value;
            }
        }
        #region ITestStep Members

        /// <summary>
        /// ITestStep.Execute() implementation
        /// </summary>
        /// <param name='testConfig'>The Xml fragment containing the configuration for this test step</param>
        /// <param name='context'>The context for the test, this holds state that is passed beteen tests</param>
        public void Execute(XmlNode testConfig, Context context)
        {
            ApplicationName = context.ReadConfigAsString(testConfig, "ApplicationName");
            ConnectionString = context.ReadConfigAsString(testConfig, "ConnectionString", true);
            SendPortName = context.ReadConfigAsString(testConfig, "SendPortName");
            if (!String.IsNullOrEmpty(context.ReadConfigAsString(testConfig, "Action")))
            {
                Action = (SendPortAction)Enum.Parse(typeof(SendPortAction), context.ReadConfigAsString(testConfig, "Action"), true);
            }
            DelayForCompletion = context.ReadConfigAsInt32(testConfig, "DelayForCompletion", true);

            Execute(context);


        }

        #endregion


        #region ITestStepOM Members

        public void Execute(Context context)
        {
            Validate(context);
            root = BizTalkStepHelper.GetRoot(ConnectionString);
            appInstance = BizTalkStepHelper.GetApplication(ApplicationName, root);
            sendPortInstance = BizTalkStepHelper.GetSendPort(appInstance, SendPortName);

            if (Action == SendPortAction.Start)
            {
                context.LogInfo("Starting send port");
                sendPortInstance.Status = PortStatus.Started;

            }
            else
            {
                context.LogInfo("Stopping send port");
                sendPortInstance.Status = PortStatus.Stopped;
            }

            root.SaveChanges();

            // Delay if necessary to allow the orchestration to start/stop
            if (DelayForCompletion > 0)
            {
                context.LogInfo("Waiting for {0} seconds before recommencing testing.", DelayForCompletion);
                System.Threading.Thread.Sleep(DelayForCompletion * 1000);
            }
        }

        public void Validate(Context context)
        {
            ArgumentValidation.CheckForEmptyString(ApplicationName, "Application Name");
            ArgumentValidation.CheckForEmptyString(SendPortName, "SendPort Name");
            ArgumentValidation.CheckForEmptyString(Action.ToString(), "SendPort Action");
        }

        #endregion
    }
}
